#nullable enable

using Application.Core.Entity;
using Application.Service.Users;
using SqlSugar;

namespace Application.Service.Auth;

/// <summary>
/// 权限检查服务
/// <para>功能：提供权限验证和访问控制功能</para>
/// <list type="bullet">
/// <item><description>权限验证</description></item>
/// <item><description>页面访问检查</description></item>
/// <item><description>操作权限检查</description></item>
/// <item><description>用户权限列表获取</description></item>
/// <item><description>超级管理员/只读用户判断</description></item>
/// </list>
/// </summary>
public class PermissionCheckService: ISingleton
{
    private readonly ISqlSugarClient _db;
    private readonly IUserService _userService;

    public PermissionCheckService(ISqlSugarClient db, IUserService userService)
    {
        _db = db;
        _userService = userService;
    }

    /// <summary>
    /// 检查用户是否拥有特定权限
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="permissionCode">权限编码</param>
    /// <returns>权限检查结果（是否拥有权限，是否为只读权限）</returns>
    public async Task<(bool hasPermission, bool isReadOnly)> CheckPermissionAsync(int userId, string permissionCode)
    {
        if (userId <= 0 || string.IsNullOrEmpty(permissionCode))
            return (false, false);

        // 检查用户是否拥有该权限
        var userPermission = await _db.Queryable<UserPermission>()
            .InnerJoin<Permission>((up, p) => up.PermissionId == p.Id)
            .Where((up, p) => up.UserId == userId && p.Code == permissionCode)
            .Select((up, p) => new { up.OnlyRead })
            .FirstAsync();

        if (userPermission != null)
        {
            return (true, userPermission.OnlyRead);
        }

        return (false, false);
    }

    /// <summary>
    /// 检查用户是否拥有页面访问权限
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="pageCode">页面编码（如：user, permission, log）</param>
    /// <returns>权限检查结果</returns>
    public async Task<(bool canAccess, bool isReadOnly)> CheckPageAccessAsync(int userId, string pageCode)
    {
        // 检查基础页面权限（如：user, permission, log）
        var (hasPermission, isReadOnly) = await CheckPermissionAsync(userId, pageCode);
        
        if (hasPermission)
        {
            return (true, isReadOnly);
        }

        return (false, false);
    }

    /// <summary>
    /// 检查用户是否拥有操作权限
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <param name="operationCode">操作编码（如：user.create, user.modify, user.delete）</param>
    /// <returns>是否拥有操作权限</returns>
    public async Task<bool> CheckOperationPermissionAsync(int userId, string operationCode)
    {
        if (userId <= 0 || string.IsNullOrEmpty(operationCode))
            return false;

        // 检查用户是否拥有该操作权限
        var hasPermission = await _db.Queryable<UserPermission>()
            .InnerJoin<Permission>((up, p) => up.PermissionId == p.Id)
            .Where((up, p) => up.UserId == userId && p.Code == operationCode)
            .AnyAsync();

        return hasPermission;
    }

    /// <summary>
    /// 获取用户所有权限列表
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>用户权限列表</returns>
    public async Task<List<Permission>> GetUserPermissionsAsync(int userId)
    {
        if (userId <= 0)
            return new List<Permission>();

        var permissions = await _db.Queryable<UserPermission>()
            .InnerJoin<Permission>((up, p) => up.PermissionId == p.Id)
            .Where((up, p) => up.UserId == userId)
            .Select((up, p) => p)
            .ToListAsync();

        return permissions;
    }

    /// <summary>
    /// 检查用户是否为超级管理员
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>是否为超级管理员</returns>
    public async Task<bool> IsSuperAdminAsync(int userId)
    {
        if (userId <= 0)
            return false;

        // 检查用户是否为Admin用户
        var user = await _userService.GetAsync(userId);
        return user?.UserName?.ToLower() == "admin";
    }

    /// <summary>
    /// 检查用户是否为只读用户
    /// </summary>
    /// <param name="userId">用户ID</param>
    /// <returns>是否为只读用户</returns>
    public async Task<bool> IsReadOnlyUserAsync(int userId)
    {
        if (userId <= 0)
            return false;

        // 检查用户是否为User用户
        var user = await _userService.GetAsync(userId);
        return user?.UserName?.ToLower() == "user";
    }
}